/**
 * @description user 控制层
 * @author LI
 */

const {
  getAccountInfo,
  createAccount,
  getAccountList,
  updatePwdById,
  deleteAccountById,
  updateLinkUserById,
  getDeductionRecordList
} = require('../services/account')
const jwt = require('jsonwebtoken')
const util = require('util')
const verify = util.promisify(jwt.verify)
const doCrypto = require('../utils/cryp')
const { ReturnResult } = require('../model/ResultModel')

const { JWT_SECRET_KEY } = require('../conf/secretKeys')
/**
 * 登录
 * @param {string} account 账号
 * @param {string} pwd 密码
 */
async function login({ account, pwd, }) {
  // 获取账号信息
  const accountInfo = await getAccountInfo(account, doCrypto(pwd))

  if (!accountInfo) {
    // 登录失败
    return new ReturnResult(0, null, false, "账号或密码错误")
  }
  // 准备写入 jwt 登录,加密 accountInfo 1d
  const token = jwt.sign(accountInfo, JWT_SECRET_KEY, { expiresIn: '30d' })

  const result = {
    id: accountInfo.id,
    name: accountInfo.name,
    typecode: accountInfo.typecode,
    typeLevel: accountInfo.typeLevel,
    balance: accountInfo.balance,
    companyAddress: accountInfo.companyAddress,
    token
  }

  return new ReturnResult(0, result, true, "登录成功")
}

/**
 * 注册账号信息/添加账号信息
 * @param {string} account 账号
 * @param {string} pwd 密码
 * @param {number} name 姓名
 * @param {string} typecode 账号类型
 * @param {string} remark 备注/要求
 */
async function addAccount({ account, pwd, name, typecode, remark }) {
  // 获取账号信息
  const accountInfo = await getAccountInfo(account)
  if (accountInfo) {
    // 账号已存在
    return new ReturnResult(0, null, false, "账号已存在")
  }
  try {
    // 接下来交给服务层，
    // 此处可以返回新增等数据库之后的信息 const user = 信息，最后返回这个 user 就是新增数据库的信息
    await createAccount({
      account,
      pwd,
      name,
      typecode,
      remark
    })
    return new ReturnResult(0, null, true, "添加成功")
  } catch (e) {
    console.error(e.message, e.stack)
    return new ReturnResult(0, null, false, "添加失败，请重试")
  }
}

/**
 * 获取全部账号信息
 * @param {string} name 姓名
 * @param {number} page 第几页
 * @param {number} limit 多少条
 * @param {number} typecode 账号类型
 * @param {string} typeLevel 二级账号类型
 */
async function getAccountAll({ name, page, limit, typecode, typeLevel }) {
  try {
    // 接下来交给服务层，
    // 此处可以返回新增等数据库之后的信息 const user = 信息，最后返回这个 user 就是新增数据库的信息
    const result = await getAccountList({
      name,
      page,
      limit,
      typecode,
      typeLevel
    })
    return new ReturnResult(result.count, result.rows, true, "查询成功")
  } catch (e) {
    console.error(e.message, e.stack)
    return new ReturnResult(0, null, false, "查询失败，请重试")
  }
}

/**
 * 获取链接用户扣款记录
 * @param {number} linkUserId 链接用户 id
 * @param {number} page 第几页
 * @param {number} limit 多少条
 */
async function getDeductionRecords({ linkUserId, page, limit }) {
  try {
    // 接下来交给服务层，
    // 此处可以返回新增等数据库之后的信息 const user = 信息，最后返回这个 user 就是新增数据库的信息
    const result = await getDeductionRecordList({
      linkUserId,
      page,
      limit,
    })
    return new ReturnResult(result.count, result.rows, true, "查询成功")
  } catch (e) {
    console.error(e.message, e.stack)
    return new ReturnResult(0, null, false, "查询失败，请重试")
  }
}

/**
 * 更新/重置密码
 * @param {object} ctx 上下文
 * @param {number} id id
 * @param {string} pwd 密码
 */
async function updatePwd({ ctx, id, pwd }) {
  const token = ctx.header.authorization
  try {
    // const payload = await verify(token.split(' ')[1], JWT_SECRET_KEY)
    // 接下来交给服务层，
    // 此处可以返回新增等数据库之后的信息 const user = 信息，最后返回这个 user 就是新增数据库的信息
    await updatePwdById({
      id,
      pwd: doCrypto(pwd),
    })
    return new ReturnResult(0, null, true, "更新成功")
  } catch (e) {
    console.error(e.message, e.stack)
    return new ReturnResult(0, null, false, "更新失败，请重试")
  }
}

/**
 * 更新/账号信息
 * @param {number} id id
 * @param {string} name 店铺名称
 * @param {string} companyAddress 店铺网址
 * @param {number} adPrice 单次扣款价格
 * @param {number} balance 余额
 */
async function updateLinkUser({ id, name, companyAddress, adPrice, balance }) {
  try {
    // 接下来交给服务层，
    // 此处可以返回新增等数据库之后的信息 const user = 信息，最后返回这个 user 就是新增数据库的信息
    await updateLinkUserById({
      id,
      name,
      companyAddress,
      adPrice,
      balance,
    })
    return new ReturnResult(0, null, true, "更新成功")
  } catch (e) {
    console.error(e.message, e.stack)
    return new ReturnResult(0, null, false, "更新失败，请重试")
  }
}

/**
 * 删除账号
 * @param {number} id id
 */
async function deleteAccount(id) {
  try {
    // 接下来交给服务层，
    // 此处可以返回新增等数据库之后的信息 const user = 信息，最后返回这个 user 就是新增数据库的信息
    await deleteAccountById(id)
    return new ReturnResult(0, null, true, "删除成功")
  } catch (e) {
    console.error(e.message, e.stack)
    return new ReturnResult(0, null, false, "删除失败，请重试")
  }
}

module.exports = {
  addAccount,
  login,
  getAccountAll,
  updatePwd,
  deleteAccount,
  updateLinkUser,
  getDeductionRecords
}
